package com.tensquare.base.service;

import com.tensquare.base.dao.LabelDao;
import com.tensquare.base.pojo.Label;
import entity.PageResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import util.IdWorker;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author Macross
 * @Type LabelService.java
 * @Desc Label相关服务
 * @date 2019/12/16 16:44
 */
@Service
public class LabelService {

    /**
     * 注入LabelDao
     */
    @Autowired
    private LabelDao labelDao;
    /**
     * 注入Id生成器
     */
    @Autowired
    private IdWorker idWorker;

    /**
     * 获取所有的标签
     * @return 所有的标签信息集合
     */
    public List<Label> findAll() {
        return labelDao.findAll();
    }

    /**
     * 通过labelId，获取指定的标签信息
     * @param labelId labelId
     * @return 指定的Label信息
     */
    public Label findLabelById(String labelId) {
        //获取指定标签信息，返回一个Optional对象
        Optional<Label> label = labelDao.findById(labelId);
        //判断Optional对象是否为空，若为空则返回null，否则返回存放在Optional对象中的Label信息
        return label.orElse(null);
    }

    /**
     * 添加标签信息
     * @param label 标签信息
     */
    public void addLabel(Label label) {
        //生成Label的id
        label.setId(idWorker.nextId()+"");
        //保存Label
        labelDao.save(label);
    }

    /**
     * 修改标签信息
     * @param label 修改后的标签信息
     */
    public void updateLabel(Label label) {
        //修改Label信息
        labelDao.save(label);
    }

    /**
     * 通过标签id，删除标签信息
     * @param labelId 需要删除的标签信息的id
     */
    public void deleteById(String labelId) {
        //通过标签id，删除指定的标签信息
        labelDao.deleteById(labelId);
    }

    /**
     * 通过条件查询,获取符合条件的标签信息
     * @param label 带有查询条件的对象
     * @return
     */
    public List<Label> search(Label label) {
        //查询查询条件
        Specification<Label> specification = createLabelSpecification(label);
        //进行条件查询,并返回结果
        return labelDao.findAll(specification);
    }

    /**
     * 通过条件查询,获取符合条件的标签信息
     * @param label 带有查询条件的对象
     * @param page 分页页码
     * @param size 分页大小
     * @return
     */
    public PageResult<Label> search(Label label, Integer page, Integer size) {
        //创建分页对象,这里必须page-1,因为是从0开始的
        Pageable pageable = PageRequest.of(page-1,size);
        //进行条件查询,并将结果进行分页
        Page<Label> labelPage = labelDao.findAll(createLabelSpecification(label), pageable);
        //对分页结果进行封装并返回
        return new PageResult<>(labelPage.getTotalElements(), labelPage.getContent());
    }

    /**
     * 查询查询条件
     * @param label 带有查询条件的对象
     * @return 查询条件对象
     */
    private Specification<Label> createLabelSpecification(Label label) {
        //创建并返回查询条件
        return (Specification<Label>) (root, criteriaQuery, criteriaBuilder) -> {
            //定义一个封装查询条件的集合
            List<Predicate> predicates = new ArrayList<>();
            //判断带有查询条件对象是否为空
            if (label!=null) {
                //判断标签名是否为空
                if (StringUtils.isNotBlank(label.getLabelName())) {
                    //添加标签名的模糊查询
                    predicates.add(criteriaBuilder.like(root.get("labelName").as(String.class),"%"+label.getLabelName()+"%"));
                }
                //判断状态值是否为空
                if (StringUtils.isNotBlank(label.getState())){
                    //添加状态值的精准查询
                    predicates.add(criteriaBuilder.equal(root.get("state").as(String.class),label.getState()));
                }
                //判断是否推荐值是否为空
                if (StringUtils.isNotBlank(label.getRecommend())){
                    //创建是否推荐的精准查询
                    predicates.add(criteriaBuilder.equal(root.get("recommend").as(String.class),label.getRecommend()));
                }
                //将集合转换为数组
                Predicate[] predicateArray = predicates.toArray(new Predicate[0]);
                //返回查询条件对象
                return criteriaBuilder.and(predicateArray);
            }
            //返回空
            return null;
        };
    }
}
